<?php
class QQApi extends ACommunityApiD {
	public $callback; // 登录回调
	public $scope; // 允许访问的应用
	public $state;
	public $code;
	const STATE_KEY = 'qq_state'; // 状态标记
	const TOKEN_KEY = 'qq_access_token'; // token认证标志
	const OPEN_ID_KEY = 'qq_openid'; // 第三方提供的唯一用户标志
	const ACCOUNT_TYPE = 3; // 帐号类型，这是3代表QQ
	protected $referUrl; // 返回到请求的页面
	public function __construct() {
		$this->init ();
	}
	/**
	 * (non-PHPdoc)
	 * 
	 * @see ACommunityApiD::getAccountType()
	 */
	public function getAccountType() {
		return self::ACCOUNT_TYPE;
	}
	/**
	 * 初始化应用参数
	 */
	public function init() {
		$this->appid = '100265676';
		$this->appkey = 'ee16b0774535364a962332e5e59dde10';
		$this->scope = 'get_user_info,add_share,list_album,add_album,upload_pic,add_topic,add_one_blog,add_weibo';
		$this->callback = Yii::app()->request->getHostInfo() . '/?r=user/login/qqLoginPost';
	}
	public function setReferUrl($referUrl) {
		$this->referUrl = $referUrl;
		$this->callback .= '&referurl=' . urlencode ( $referUrl );
	}
	public function getReferUrl() {
		return $this->referUrl;
	}
	/**
	 * 登录到QQ认证中心
	 */
	public function login() {
		$state = md5 ( uniqid ( rand (), TRUE ) ); // CSRF protection
		Yii::app ()->frontuser->setState ( self::STATE_KEY, $state );
		if (Yii::app ()->frontuser->getState ( self::STATE_KEY ) == '') {
			// 解决memcached命中问题
			Yii::app ()->frontuser->setState ( self::STATE_KEY, $state );
		}
		$login_url = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=" . $this->appid . "&redirect_uri=" . urlencode ( $this->callback ) . "&state=" . $state . "&scope=" . $this->scope;
		header ( "Location:$login_url" );
		// echo "<script type='text/javascript'>window.open ('{$login_url}',
	// 'QQ', 'height=500, width=500, top=400, left=300, toolbar=no, menubar=no,
	// scrollbars=no, resizable=no,location=n o, status=no');</script>";
	
	}
	/**
	 * 获取访问Token
	 */
	public function getToken() {
		return Yii::app ()->frontuser->getState ( self::TOKEN_KEY );
	}
	/**
	 * 获取open id
	 */
	public function getOpenId() {
		return Yii::app ()->frontuser->getState ( self::OPEN_ID_KEY );
	}
	/**
	 * 执行回调处理
	 */
	public function callback() {
		if ($this->parseCallback ( $this->state, $this->code )) {
			return $this->parseOpenId ();
		}
		return false;
	}
	/**
	 * 分析回调
	 */
	public function parseCallback($state = '', $code = '') {
		if (Yii::app ()->frontuser->hasState ( self::STATE_KEY ) && $state == Yii::app ()->frontuser->getState ( self::STATE_KEY )) {
			try {
				$token_url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&" . "client_id=" . $this->appid . "&redirect_uri=" . urlencode ( $this->callback ) . "&client_secret=" . $this->appkey . "&code=" . $code;
				$this->httpclient = new HttpClientD ( $token_url );
				$this->httpclient->open ();
				$response = $this->httpclient->excute ();
				if (strpos ( $response, "callback" ) !== false) {
					$lpos = strpos ( $response, "(" );
					$rpos = strrpos ( $response, ")" );
					$response = substr ( $response, $lpos + 1, $rpos - $lpos - 1 );
					$msg = json_decode ( $response );
					if (isset ( $msg->error )) {
						$this->setErrorMsg('疑有非法操作，请勿刷新网页或者返回操作');
						//$this->setErrorMsg ( '错误代码：' . $msg->error . ', 错误信息：' . $msg->error_description );
						return false;
					}
				}
				$params = array ();
				parse_str ( $response, $params );
				if(isset($params ["access_token"])){
					Yii::app ()->frontuser->setState ( self::TOKEN_KEY, $params ["access_token"] );
					return true;
				}else{
					$this->setErrorMsg('疑有非法操作，请勿刷新网页或者返回操作');
					return false;
				}
			} catch ( Exception $e ) {
				$this->setErrorMsg ( '异常错误, 请重试' );
				return false;
			}
		} else {
			$this->setErrorMsg('疑有非法操作，请勿刷新网页或者返回操作');
			return false;
		}
	}
	/**
	 * 获取open id
	 */
	function parseOpenId() {
		try {
			$graph_url = "https://graph.qq.com/oauth2.0/me?access_token=" . $this->getToken ();
			$this->httpclient = new HttpClientD ( $graph_url );
			$this->httpclient->open ();
			$response = $this->httpclient->excute ();
			if (strpos ( $response, "callback" ) !== false) {
				$lpos = strpos ( $response, "(" );
				$rpos = strrpos ( $response, ")" );
				$response = substr ( $response, $lpos + 1, $rpos - $lpos - 1 );
			}
			
			$user = json_decode ( $response );
			if (is_null ( $user )) {
				$this->setErrorMsg ( '解析数据异常错误' );
				return false;
			}
			if (isset ( $user->error )) {
				$this->setErrorMsg ( '错误代码：' . $msg->error . ', 错误信息：' . $msg->error_description );
				return false;
			}
			Yii::app ()->frontuser->setState ( self::OPEN_ID_KEY, $user->openid );
			return true;
		} catch ( Exception $e ) {
			$this->setErrorMsg ( '异常错误' );
			return false;
		}
	}
	/**
	 * 获取用户信息
	 * 
	 * @return mixed
	 */
	function getUserInfo() {
		$get_user_info = "https://graph.qq.com/user/get_user_info?" . "access_token=" . $this->getToken () . "&oauth_consumer_key=" . $this->appid . "&openid=" . $this->getOpenId () . "&format=json";
		
		$this->httpclient = new HttpClientD ( $get_user_info );
		$this->httpclient->open ();
		$response = $this->httpclient->excute ();
		$arr = json_decode ( $response );
		if (is_null ( $arr )) {
			return false;
		}
		return $arr;
	}
}

?>